/**
 * File: 
 * Proj/Lab:
 * Author:
 * Date:
 * Section:
 * Email:
 */
package proj;

import java.util.ArrayList;

/**
 * @author Ben
 *
 */
public class VirtualAdvisor 
{
	private boolean isAdmin = false;
	private User presentUser = null;
	private ArrayList<Degree> degrees = new ArrayList<Degree>(); 
	private Catalog catalog = new Catalog();
	
	public VirtualAdvisor(ArrayList<Degree> myDegrees, ArrayList<Course> myCatalog)
	{
		degrees = myDegrees;
		catalog = new Catalog(myCatalog);
	}
	
	public void userLogin(User newUser, boolean isUserAdmin)
	{
		presentUser = newUser;
		isAdmin = isUserAdmin;
	}
	
	public void userLogout()
	{
		presentUser = null;
		isAdmin = false;
	}
	
	public double calculateOverallGPA(String planName)
	{
		if(isAdmin)
		{
			//admin does not have this functionality
			//throw exception
		}
		
		double gpa = 0;
		int pointsEarned = 0;
		int creditsEarned = 0;
		
		ArrayList<Plan> myPlans = ((Student)presentUser).getPlans();
		Plan myPlan = getPlanWithName(myPlans, planName);
		
		if(myPlan == null)
		{
			//plan with planName not found
			//throw Exception
		}
		
		ArrayList<Semester> mySemesters = myPlan.getSemesters();
		
		for(int i = 0; i != mySemesters.size(); i++)
		{
			Semester presentSemester = mySemesters.get(i);
			pointsEarned += calculatePointsEarnedInSemester(presentSemester);
			creditsEarned += calculateCreditsInSemester(presentSemester);
		}
		
		gpa = pointsEarned/creditsEarned;
		
		return gpa;
	}
	
	public double calculateSemesterGPA(String planName, int season, int year)
	{
		if(isAdmin)
		{
			//admin does not have this functionality
			//throw exception
		}
		
		double gpa = 0;
		int coursesTaken = 0;
		
		ArrayList<Plan> myPlans = ((Student)presentUser).getPlans();
		Plan myPlan = getPlanWithName(myPlans, planName);
		
		if(myPlan == null)
		{
			//plan with planName not found
			//throw Exception
		}
		
		ArrayList<Semester> mySemesters = myPlan.getSemesters();
		Semester mySemester = getSemesterWithSeasonAndYear(mySemesters, season, year);
		
		if(mySemester == null)
		{
			//semester with season and year not found in plan planName
			//throw exception
		}
		
		ArrayList<CourseRecord> myCourses = mySemester.getCourseRecords();
		coursesTaken = myCourses.size();
		gpa = calculatePointsEarnedInSemester(mySemester)/coursesTaken;
		
		return gpa;
	}
	
	private int calculateCreditsInSemester(Semester mySemester)
	{
		ArrayList<CourseRecord> myCourses = mySemester.getCourseRecords();
		int credits = 0;
		for(int i = 0; i != myCourses.size(); i++)
		{
			CourseRecord cr = myCourses.get(i);
			credits += catalog.getCourse(cr.getCourseID()).getNumCreds();
		}
		
		return credits;
	}
	
	private int calculatePointsEarnedInSemester(Semester mySemester)
	{
		ArrayList<CourseRecord> myCourses = mySemester.getCourseRecords();
		int points = 0;
		for(int i = 0; i != myCourses.size(); i++)
		{
			CourseRecord cr = myCourses.get(i);
			int numCreds = catalog.getCourse(cr.getCourseID()).getNumCreds();
			int grade = gradeToInt(cr.getGrade());
			points += (grade*numCreds); 
		}
		
		return points;
	}
	
	private int gradeToInt(char grade)
	{
		if(grade == 'A') return 4;
		else if(grade == 'B') return 3;
		else if(grade == 'C') return 2;
		else if(grade == 'D') return 1;
		else return 0;
	}
	
	private Semester getSemesterWithSeasonAndYear(ArrayList<Semester> mySemesters, int season, int year)
	{
		for(int i = 0; i != mySemesters.size(); i++)
		{
			int trialSeason = mySemesters.get(i).getSeason();
			int trialYear = mySemesters.get(i).getYear();
			if((season == trialSeason) && (year == trialYear))
			{
				return mySemesters.get(i);
			}
		}
		
		return null;
	}
	
	private Plan getPlanWithName(ArrayList<Plan> myPlans, String planName)
	{
		for(int i = 0; i != myPlans.size(); i++)
		{
			String trialName = myPlans.get(i).getPlanName();
			if(trialName.compareTo(planName) == 0)
			{
				return myPlans.get(i);
			}
		}
		return null;
	}
	
}
